package com.ayg.test.apitest.core;
import com.ayg.test.apitest.entity.TestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.*;
import org.testng.xml.XmlSuite;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SimpleReporterListener implements IReporter {
    private static final Logger logger = LoggerFactory.getLogger(SimpleReporterListener.class);
    private static final String OUTPUT_FOLDER = "test-output/";
    private static final String FILE_NAME = "simple_report.html";
    private static final String START_TD = "<td>";
    private static final String END_TD = "</td>";

    private  String htmlTxt="<html> <head> <title></title> <style type=\"text/css\"> table { border-collapse: collapse; margin: 0 auto; text-align: center; } table td, table th { border: 1px solid #cad9ea; color: #666; height: 30px; } table thead th { background-color: #CCE8EB; width: 100px; } table tr:nth-child(odd) { background: #fff; } table tr:nth-child(even) { background: #F5FAFA; } </style> </head> <body> <table width=\"90%\" class=\"table\"><h4>%summary%</h4><caption> <h2> %reportName%接口自动化测试报告</h2> </caption> <thead> <tr> <th> 状态 </th> <th> 用例名 </th> <th> 接口名 </th> <th> 失败原因 </th> </tr> </thead> %content% </table> </body> </html>";
    private StringBuilder successContent = new StringBuilder();
    private StringBuilder failContent = new StringBuilder();

    @Override
    public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
        int failTestsCount = 0;
        int successTestsCount = 0;
        for (ISuite suite : suites) {
            Map<String, ISuiteResult> result = suite.getResults();
            for (ISuiteResult r : result.values()) {
                ITestContext context = r.getTestContext();
                failTestsCount = failTestsCount + context.getFailedTests().size();
                successTestsCount = successTestsCount + context.getPassedTests().size();
                IResultMap testFailed = context.getFailedTests();
                printContent(testFailed,failContent);
                IResultMap testSuccess = context.getPassedTests();
                printContent(testSuccess,successContent);
            }
        }
        String reportName = xmlSuites.get(0).getName();
        htmlTxt = htmlTxt.replace("%reportName%",reportName);
        BigDecimal testsCount = new BigDecimal(failTestsCount+successTestsCount);
        BigDecimal successTestsCountDec = new BigDecimal(successTestsCount);
        StringBuilder testSummary = new StringBuilder();
        testSummary.append("共：").append(testsCount)
                .append("    失败：").append(failTestsCount)
                .append("    成功：").append(successTestsCount)
                .append("    通过率：").append(successTestsCountDec.divide(testsCount,2,BigDecimal.ROUND_HALF_DOWN).doubleValue()*100).append("%");
        htmlTxt = htmlTxt.replace("%summary%",testSummary.toString());
        failContent.append(successContent.toString());
        htmlTxt = htmlTxt.replace("%content%",failContent.toString());
        writeReport();
    }

    private void writeReport() {
        //文件夹不存在的话进行创建
        File reportDir= new File(OUTPUT_FOLDER);
        if(!reportDir.exists()&& !reportDir .isDirectory()){
            reportDir.mkdir();
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String subDirName = format.format(new Date());
        reportDir= new File(OUTPUT_FOLDER+subDirName);
        if(!reportDir.exists()&& !reportDir .isDirectory()){
            reportDir.mkdir();
        }
        format = new SimpleDateFormat("HHmmss");
        String reportPath = reportDir.getPath()+File.separator + format.format(new Date())
                + "_"+FILE_NAME;
        try(FileWriter fileWriter = new FileWriter(reportPath)) {
            fileWriter.write(htmlTxt);
            fileWriter.flush();
        } catch (IOException e) {
            logger.error("{}",e);
        }
    }

    private void printContent(IResultMap tests,StringBuilder content) {
        content.append("<tr>");
        Set<ITestResult> results = tests.getAllResults();
        for(ITestResult result1 : results){
            String status = "";
            if(result1.getStatus() == ITestResult.FAILURE){
                status = "<font color='#FF0000'>Fail</font>";
            }else if(result1.getStatus() == ITestResult.SUCCESS){
                status = "Pass";
            }
            content.append(START_TD).append(status).append(END_TD);
            Object[] objects = result1.getParameters();
            for(Object o : objects){
                TestCase testCase  = (TestCase)o;
                content.append(START_TD).append(testCase.getName()).append(END_TD);
                content.append(START_TD).append(testCase.getRequest().getUrl()).append(END_TD);
            }
            content.append(START_TD);
            if(result1.getThrowable() != null) {
                content.append(result1.getThrowable().getMessage());
            }
            content.append(END_TD);
            content.append("</tr>");
        }
    }
}
